package com.lxmes.sales.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.lxmes.base.domain.NcTechDetail;
import com.lxmes.base.mapper.NcTechDetailMapper;
import com.lxmes.common.utils.DateUtils;
import com.lxmes.common.utils.NewNumber;
import com.lxmes.common.utils.SecurityUtils;
import com.lxmes.sales.domain.*;
import com.lxmes.sales.mapper.NcOrderResourcesYsMapper;
import com.lxmes.sales.mapper.NcSalesOrderMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.lxmes.sales.service.INcOrderResourcesYsService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 订单资源验算Service业务层处理
 *
 * @author ruoyi
 * @date 2022-12-08
 */
@Service
public class NcOrderResourcesYsServiceImpl implements INcOrderResourcesYsService
{
    @Resource
    private NcOrderResourcesYsMapper ncOrderResourcesYsMapper;

    @Resource
    private NcSalesOrderMapper ncSalesOrderMapper;

    @Resource
    private NcTechDetailMapper ncTechDetailMapper;




    /**
     * 查询订单资源验算
     *
     * @param id 订单资源验算主键
     * @return 订单资源验算
     */
    @Override
    public NcOrderResourcesYs selectNcOrderResourcesYsById(Long id)
    {
        return ncOrderResourcesYsMapper.selectNcOrderResourcesYsById(id);
    }

    /**
     * 查询订单资源验算列表
     *
     * @param ncOrderResourcesYs 订单资源验算
     * @return 订单资源验算
     */
    @Override
    public List<NcOrderResourcesYs> selectNcOrderResourcesYsList(NcOrderResourcesYs ncOrderResourcesYs)
    {
        ncOrderResourcesYs.setFactoryCode(SecurityUtils.getFactoryCode());
        return ncOrderResourcesYsMapper.selectNcOrderResourcesYsList(ncOrderResourcesYs);
    }

    /**
     * 新增订单资源验算
     *
     * @param ncOrderResourcesYs 订单资源验算
     * @return 结果
     */
    @Override
    public int insertNcOrderResourcesYs(NcOrderResourcesYs ncOrderResourcesYs)
    {
        return ncOrderResourcesYsMapper.insertNcOrderResourcesYs(ncOrderResourcesYs);
    }

    /**
     * 修改订单资源验算
     *
     * @param ncOrderResourcesYs 订单资源验算
     * @return 结果
     */
    @Override
    public int updateNcOrderResourcesYs(NcOrderResourcesYs ncOrderResourcesYs)
    {
        return ncOrderResourcesYsMapper.updateNcOrderResourcesYs(ncOrderResourcesYs);
    }

    /**
     * 批量删除订单资源验算
     *
     * @param ids 需要删除的订单资源验算主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteNcOrderResourcesYsByIds(Long[] ids)
    {
        for(long id : ids){
            NcOrderResourcesYs ncOrderResourcesYs = ncOrderResourcesYsMapper.selectNcOrderResourcesYsById(id);
            NcSalesOrder ncSalesOrder = new NcSalesOrder();
            ncSalesOrder.setId(ncOrderResourcesYs.getSalesOrderId());
            ncSalesOrder.setIsYsed("0");
            ncSalesOrderMapper.updateNcSalesOrder(ncSalesOrder);
        }
        return ncOrderResourcesYsMapper.deleteNcOrderResourcesYsByIds(ids);
    }

    /**
     * 删除订单资源验算信息
     *
     * @param id 订单资源验算主键
     * @return 结果
     */
    @Override
    public int deleteNcOrderResourcesYsById(Long id)
    {
        return ncOrderResourcesYsMapper.deleteNcOrderResourcesYsById(id);
    }

    @Override
    @Transactional
    public void handYs(Long[] ids) {
        String dh = "CGJH-"+ NewNumber.createNewNumber(ncSalesOrderMapper.getCaiGouNewCode(DateUtils.getDate()));
        String ckdh = "CKJH-"+ NewNumber.createNewNumber(ncSalesOrderMapper.getChukuNewCode(DateUtils.getDate()));
        //1:统读取销售正式订单、工艺明细表、查找库存明细表可用库存  订单查询一定是按照创建时间顺序进行查询  验算以及预排的顺序也是创建顺序
        List<NcSalesOrder> ncSalesOrders = new LinkedList<>();
        for(long id : ids){
          NcSalesOrder ncSalesOrderEntity = ncSalesOrderMapper.selectNcSalesOrderById(id);
            String isYsed = ncSalesOrderEntity.getIsYsed();
            if("1".equals(isYsed)){
                throw new RuntimeException("订单号【"+ncSalesOrderEntity.getOrderNumber()+"】已经验算完成不能继续验算！");
            }else{
                ncSalesOrders.add(ncSalesOrderEntity);
            }
      }
        ncSalesOrders.stream().forEach(order ->{
            NcOrderResourcesYs ncOrderResourcesYs = new NcOrderResourcesYs();
            BeanUtils.copyProperties(order,ncOrderResourcesYs);
            ncOrderResourcesYs.setHth(order.getContractNo());
            ncOrderResourcesYs.setOrderNo(order.getOrderNumber());
            ncOrderResourcesYs.setOrderNumber(order.getNumber());
            ncOrderResourcesYs.setCreateBy(SecurityUtils.getUsername());
            ncOrderResourcesYs.setCreateTime(new Date());
            ncOrderResourcesYs.setItemId(order.getItemCode());
            ncOrderResourcesYs.setItemName(order.getItemName());
            ncOrderResourcesYs.setSalesOrderId(order.getId());
            List<CcStockInfoVo> stockInfos = ncOrderResourcesYsMapper.getStockInfoBySubCode(order.getItemCode());
            long actualNum = order.getNumber();
            if(stockInfos.size()>0){
                String kwbm = "";
                String kwNum = "";
                for(int i=0;i<stockInfos.size();i++){
                    if(i==stockInfos.size()-1){
                        kwbm += stockInfos.get(i).getKuweiCode();
                        kwNum += stockInfos.get(i).getKyNum();
                    }else{
                        kwbm += stockInfos.get(i).getKuweiCode()+",";
                        kwNum += stockInfos.get(i).getKyNum()+",";
                    }
                }
                BigDecimal kyTotal = stockInfos.stream().map(CcStockInfoVo::getKyNum).reduce((a, b) -> (a.add(b))).get();
                if(kyTotal.longValue()>=actualNum){
                    ncOrderResourcesYs.setWarehouseShortageQuantity(0L);
                    lockAccountByLocation(stockInfos, (int) actualNum);
                    long syNum = actualNum;
                    for(CcStockInfoVo ccStockInfoVo : stockInfos){
                        BigDecimal kyNum = ccStockInfoVo.getKyNum();
                        if(kyNum.longValue()>=syNum){
                            startChuku(syNum,order,ckdh,ccStockInfoVo);
                            break;
                        }else{
                            startChuku(kyNum.longValue(),order,ckdh,ccStockInfoVo);
                            syNum = syNum - kyNum.longValue();
                        }
                    }
                }else {
                    long difference = actualNum-kyTotal.longValue();
                    ncOrderResourcesYs.setWarehouseShortageQuantity(difference);
                    lockAccountByLocation(stockInfos, kyTotal.intValue());
                    purchase(difference,order,dh);
                    for(CcStockInfoVo ccStockInfoVo : stockInfos){
                        startChuku(ccStockInfoVo.getKyNum().longValue(),order,ckdh,ccStockInfoVo);
                    }

                }
                ncOrderResourcesYs.setKcNum(kyTotal.longValue());
                ncOrderResourcesYs.setUnit(order.getUnit());
//                ncOrderResourcesYs.setDtyl(Long.valueOf(tech.getDtyl()));
                ncOrderResourcesYs.setTotalOrderUsage(actualNum);
                ncOrderResourcesYs.setLockedAccountQuantity(actualNum);
                ncOrderResourcesYs.setLockedTime(new Date());
                ncOrderResourcesYs.setWarehouseCode(stockInfos.get(0).getStockId());
                ncOrderResourcesYs.setStockName(stockInfos.get(0).getStockName());
                ncOrderResourcesYs.setKuquCode(stockInfos.get(0).getKuquCode());
                ncOrderResourcesYs.setKuquName(stockInfos.get(0).getKuquName());
                ncOrderResourcesYs.setKwbm(kwbm);
                ncOrderResourcesYs.setCreateTime(new Date());
                ncOrderResourcesYs.setCreateBy(SecurityUtils.getUsername());
                ncOrderResourcesYs.setDeptId(SecurityUtils.getDeptId());
//                    ncOrderResourcesYs.setKwNum(kwNum);
                ncOrderResourcesYsMapper.insertNcOrderResourcesYs(ncOrderResourcesYs);
            }else{
                ncOrderResourcesYs.setWarehouseShortageQuantity(actualNum);
                ncOrderResourcesYs.setKcNum(0L);
                ncOrderResourcesYs.setUnit(order.getUnit());
                ncOrderResourcesYs.setTotalOrderUsage(actualNum);
                ncOrderResourcesYs.setLockedAccountQuantity(0L);
                ncOrderResourcesYs.setCreateTime(new Date());
                ncOrderResourcesYs.setCreateBy(SecurityUtils.getUsername());
                ncOrderResourcesYs.setDeptId(SecurityUtils.getDeptId());
                ncOrderResourcesYsMapper.insertNcOrderResourcesYs(ncOrderResourcesYs);
                purchase(actualNum,order,dh);
            }
            NcSalesOrder param = new NcSalesOrder();
            param.setIsYsed("1");
            param.setId(order.getId());
            ncSalesOrderMapper.updateNcSalesOrder(param);
        });

    }


    /*
    *
    * 查询总库存明细对于该产品的组装是否满足订单数量
    * */
    public int kkgjlc(String cpbm){
        int min = 0;
        List<Integer> integerList = new ArrayList<>();
        NcTechDetail ncTechDetail = new NcTechDetail();
        ncTechDetail.setCpbm(cpbm);
        List<NcTechDetail> ncTechDetails = ncTechDetailMapper.selectNcTechDetailList(ncTechDetail);
        ncTechDetails.stream().forEach(tech->{
            int dtyl = Integer.parseInt(tech.getDtyl());
            List<CcStockInfoVo> stockInfos = ncOrderResourcesYsMapper.getStockInfoBySubCode(tech.getItemCode());
            BigDecimal kyTotal = stockInfos.stream().map(CcStockInfoVo::getKyNum).reduce((a, b) -> (a.add(b))).get();
            int copies = kyTotal.intValue()/dtyl;
            integerList.add(copies);
        });
        min = integerList.stream().reduce(integerList.get(0), Integer::min);
        return min;
    }

        /*
        *
        *自动进入采购流程
        *
        * */
    public void purchase(long wxNum,NcSalesOrder order,String dh){
        CcPurchaseInfoVo ccPurchaseInfoVo = new CcPurchaseInfoVo();
        ccPurchaseInfoVo.setFactoryName(SecurityUtils.getFactoryName());
        ccPurchaseInfoVo.setFactoryCode(SecurityUtils.getFactoryCode());
        ccPurchaseInfoVo.setDanhao(dh);
        ccPurchaseInfoVo.setCreateTime(DateUtils.getNowDate());
        ccPurchaseInfoVo.setCreateBy(SecurityUtils.getUsername());
        ccPurchaseInfoVo.setYhType("排产验算");
        ccPurchaseInfoVo.setYhDanhao(dh);
        ccPurchaseInfoVo.setItemId(order.getItemCode());
        ccPurchaseInfoVo.setItemName(order.getItemName());
        ccPurchaseInfoVo.setSpec(order.getProductModel());
        ccPurchaseInfoVo.setYhNum(new BigDecimal(wxNum));
        ccPurchaseInfoVo.setYddNum(new BigDecimal(wxNum));
        ccPurchaseInfoVo.setJhUnitPrice(order.getJhUnitPrice());
        ccPurchaseInfoVo.setUnitPrice(order.getContractUnitPrice());
        ccPurchaseInfoVo.setJhTotalPrice(order.getJhUnitPrice().multiply(new BigDecimal(wxNum)));
        ccPurchaseInfoVo.setTotalPrice(order.getContractUnitPrice().multiply(new BigDecimal(wxNum)));
        ccPurchaseInfoVo.setYhCompany(order.getClientName());
        ccPurchaseInfoVo.setAsnDanhao(order.getOrderNumber());
        ncSalesOrderMapper.insertCcPurchaseInfo(ccPurchaseInfoVo);
    }


    /*
    * param 库位物料明细  锁账数量
    * return 0-代表全部锁账完成   大于0代表本身物料不足
    * */
    public int lockAccountByLocation(List<CcStockInfoVo> stockInfos,int lockNum) {
        int surplusQuantity = lockNum;
        for(CcStockInfoVo ccStockInfoVo:stockInfos){
            //1:这一种货物有多个库位存放  怎么锁呢？
            BigDecimal kyNum = ccStockInfoVo.getKyNum();
            if(kyNum.intValue()>=surplusQuantity){
                ccStockInfoVo.setResourceLocking(ccStockInfoVo.getResourceLocking().add(new BigDecimal(surplusQuantity)));
                ccStockInfoVo.setKyNum(ccStockInfoVo.getKyNum().subtract(new BigDecimal(surplusQuantity)));
                ccStockInfoVo.setId(ccStockInfoVo.getId());
                ccStockInfoVo.setVersion(ccStockInfoVo.getVersion());
                ncOrderResourcesYsMapper.updateStockLockNum(ccStockInfoVo);
                break;
            }else{
                ccStockInfoVo.setResourceLocking(ccStockInfoVo.getResourceLocking().add(kyNum));
                ccStockInfoVo.setKyNum(BigDecimal.valueOf(0));
                ccStockInfoVo.setId(ccStockInfoVo.getId());
                ccStockInfoVo.setVersion(ccStockInfoVo.getVersion());
                ncOrderResourcesYsMapper.updateStockLockNum(ccStockInfoVo);
                surplusQuantity = lockNum - kyNum.intValue();
            }
        }
        return surplusQuantity;
    }


    public void startChuku(long chukuNum,NcSalesOrder order,String dh,CcStockInfoVo ccStockInfoVo){
        CcChukuInfoPlanPo ccChukuInfoPlanPo = new CcChukuInfoPlanPo();
        ccChukuInfoPlanPo.setFactoryCode(order.getFactoryCode());
        ccChukuInfoPlanPo.setFactoryName(order.getFactoryName());
        ccChukuInfoPlanPo.setDanhao(dh);
        ccChukuInfoPlanPo.setChukuType(2L);
        ccChukuInfoPlanPo.setCkNum(new BigDecimal(chukuNum));
        ccChukuInfoPlanPo.setChukuDate(new Date());
        ccChukuInfoPlanPo.setItemCode(order.getItemCode());
        ccChukuInfoPlanPo.setItemId(order.getItemCode());
        ccChukuInfoPlanPo.setItemName(order.getItemName());
        ccChukuInfoPlanPo.setSpec(order.getProductModel());
        ccChukuInfoPlanPo.setUnit(order.getUnit());
        ccChukuInfoPlanPo.setLot(ccStockInfoVo.getLot());
        ccChukuInfoPlanPo.setStockId(ccStockInfoVo.getStockId());
        ccChukuInfoPlanPo.setStockName(ccStockInfoVo.getStockName());
        ccChukuInfoPlanPo.setKuquCode(ccStockInfoVo.getKuquCode());
        ccChukuInfoPlanPo.setKuquName(ccStockInfoVo.getKuquName());
        ccChukuInfoPlanPo.setKuweiCode(ccStockInfoVo.getKuweiCode());
        ccChukuInfoPlanPo.setCreateTime(new Date());
        ccChukuInfoPlanPo.setCreateBy(SecurityUtils.getUsername());
        ccChukuInfoPlanPo.setDeptId(SecurityUtils.getDeptId());
        ncOrderResourcesYsMapper.insertCcChukuInfoPlan(ccChukuInfoPlanPo);
    }


}
